# -*- shell-script -*-

# 00minimal - Default routine for querying lsvpd database.

# This file is part of the Linux lsvpd package.

# (C) Copyright IBM Corp. 2002, 2003, 2004, 2005

# Maintained by  Martin Schwenke <martins@au.ibm.com>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
# $Id: 00minimal,v 1.1 2006/04/11 18:38:28 emunson Exp $

# This module is always loaded.
true || return 0

######################################################################

usage ()
{
    cat <<EOF 1>&2
usage: $0 ...

Incorrect usage.  Please implement the usage() function.
EOF
    exit 1
}

process_options ()
{
    :
}

######################################################################

ensure_db ()
{
    if [ ! -d "$db" ] ; then
	printf "$0: Error - database not initialised \"${db}\".
\tPlease run \"/sbin/update-lsvpd-db\".\n" 1>&2
	exit 1
    fi
}

######################################################################

list_linux_vpd ()
{
    list_linux_vpd_basic "$db_bus_dir"
}

list_linux_vpd_basic ()
{
    local dir="$1"

    local f d

    # This code used to use trailing slashes on directory names (in
    # the echo statement below).  This was used to fix a bug in the
    # sort order that is seen in lscfg output.  Consider the case
    # where we have the following directories containing VPD:
    #
    #   .../scsi@1
    #   .../scsi@1,1
    #   .../scsi@1,1/disk@1
    #   .../scsi@1/disk@1
    #
    # The above is the standard ASCII sort order, so the last disk
    # listed is on the first adapter, which is wrong.  If a trailing
    # slash is added to each directory, the sort order changes to:
    #
    #   .../scsi@1,1/
    #   .../scsi@1,1/disk@1/
    #   .../scsi@1/
    #   .../scsi@1/disk@1/
    # 
    # which associates each disk with its correct adapter... even
    # though it results in a slightly weird order for the overall
    # output.
    #
    # To get a more natural sort order in lscfg output it is better to
    # use a (temporary) directory separator that appears before
    # everything else in the collating sequence.  If this were being
    # coded in C it would probably be good to use '\001'.  However, in
    # bash '!' is a good choice, since it appears before most things,
    # and doesn't tend to appear in device-tree or sysfs paths.
    #
    # Therefore, before sorting we replace all '/'s in directory names
    # with '!'s and add a trailing '!'.  After sorting we simply
    # replace all '!'s with '/'s.  Simple really.
    find "${dir}" -name linux,vpd | \
    while read f ; do
	local t="${f%/*}" # dirname
        echo "${t//\//!}!"
    done | \
    sort | \
    while read d ; do
        d="${d//!//}"
	if node_contains_dynamic_vpd "$d" ; then
	    should_show_dynamic_vpd && \
		echo "${d}linux,vpd"
	else
	    echo "${d}linux,vpd"
	fi
    done
}

should_render ()
{
    should_render_basic "$@"
}

should_render_basic ()
{
    # Uses: name

    local dir="$1"
    local ds="$2"
    local ax="$3"
    local yl="$4"

    if [ -n "$name" ] ; then
	case "$ax" in
	    ($name) return 0 ;;
	    (*)     return 1 ;;
	esac
    else
	return 0
    fi
}

render_all ()
{
    render_all_basic "$@"
}

render_all_basic ()
{
    local vpd

    while read vpd ; do
	render_linux_vpd "$vpd"
    done
}

print_global_header ()
{
    :
}

######################################################################

get_model ()
{
    get_model_basic
}

get_serial ()
{
    get_serial_basic
}

get_model_basic ()
{
    local model

    local f="${db_misc_dir}/model"
    [ -r "$f" ] && read model <"$f"

    if [ -z "$model" ] ; then
	f="${db_proc_dir}/cpuinfo"
	if [ -r "$f" ] ; then
	    local i
	    for i in "machine" "model name" ; do
		# This gets the first CPU - so it works on SMP.
		model=$(sed -n -e "s/^${i}[ \t]*:[ \t]*//p" "$f" | \
		    { local x ; read x ; echo $x ; } )
		[ -n "$model" ] && break
	    done
	fi
    fi

    [ -n "$model" ] || model="unknown"

    echo "$model"
}

get_serial_basic ()
{
    local serial

    local f="${db_misc_dir}/serial"
    [ -r "$f" ] && read serial <"$f"

    if [ -z "$serial" ] ; then
	f="${db_uname_dir}/nodename"
	[ -r "$f" ] && read serial <"$f"
    fi

    [ -n "$serial" ] || serial="unknown"

    echo "$serial"
}
